package com.zdxlz.fcmp.common.core.util;

import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import javax.net.ssl.*;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.stream.Stream;

import static com.baomidou.mybatisplus.core.toolkit.StringPool.*;

/**
 * @className HttpUtil
 * @description
 * @author: aman
 * @date 2025/2/1 21:08
 */
@Slf4j
@Setter
public class HttpUtil {


    private static final HttpClient httpClient;

    static {
        System.setProperty("jdk.internal.httpclient.disableHostnameVerification", "true");
        try {
            // 创建一个 TrustManager 来信任所有证书
            TrustManager[] trustAllCertificates = new TrustManager[]{
                    new X509TrustManager() {
                        public X509Certificate[] getAcceptedIssuers() {
                            return null; // 无条件接受所有证书
                        }

                        public void checkClientTrusted(X509Certificate[] certs, String authType) {
                        }

                        public void checkServerTrusted(X509Certificate[] certs, String authType) {
                        }
                    }
            };


            // 配置 SSLContext TrustManager
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustAllCertificates, new java.security.SecureRandom());

            // 使用自定义的 SSLContext 创建 HttpClient
            httpClient = HttpClient.newBuilder()
                    .sslContext(sslContext) // 设置自定义 SSLContext
                    .executor(createExecutor()) // 设置线程池
                    .build();
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            log.error("初始化HttpClient失败");
            throw new RuntimeException("Error initializing HttpClient", e);
        }
    }

    /**
     * 发送GET请求
     *
     * @param url 请求的URL
     * @return 响应字符串
     * @throws IOException          如果发生I/O错误
     * @throws InterruptedException 如果请求被中断
     */
    public static String doGet(String url) throws IOException, InterruptedException {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .GET()
                .build();

        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
        return response.body();
    }

    /**
     * 发送带有自定义头的GET请求
     *
     * @param url     请求的URL
     * @param headers 自定义请求头
     * @return 响应字符串
     * @throws IOException          如果发生I/O错误
     * @throws InterruptedException 如果请求被中断
     */
    public static String doGetWithHeaders(String url, Map<String, String> headers) throws IOException, InterruptedException {
        HttpRequest.Builder requestBuilder = HttpRequest.newBuilder().uri(URI.create(url));
        headers.forEach(requestBuilder::header);

        HttpRequest request = requestBuilder.GET().build();
        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

        return response.body();
    }


    /**
     * 发送带有查询参数的GET请求
     *
     * @param baseUrl 请求的基础URL
     * @param params  查询参数
     * @return 响应字符串
     * @throws Exception 如果发生任何错误
     */
    public static String getWithParams(String baseUrl, Map<String, String> params) throws IOException, InterruptedException, URISyntaxException {
        String urlWithParams = buildUrlWithParams(baseUrl, params);
        HttpRequest request = HttpRequest.newBuilder()
                .uri(new URI(urlWithParams))
                .GET()
                .build();

        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
        return response.body();
    }

    /**
     * 构建带有查询参数的URL
     *
     * @param baseUrl 基础URL
     * @param params  查询参数
     * @return 包含查询参数的完整URL
     */
    private static String buildUrlWithParams(String baseUrl, Map<String, String> params) {
        StringBuilder urlBuilder = new StringBuilder(baseUrl);

        boolean isFirstParam = true;
        for (Map.Entry<String, String> param : params.entrySet()) {
            if (isFirstParam && !baseUrl.contains(QUESTION_MARK)) {
                urlBuilder.append(QUESTION_MARK);
                isFirstParam = false;
            } else {
                urlBuilder.append(AMPERSAND);
            }
            urlBuilder.append(URLEncoder.encode(param.getKey(), StandardCharsets.UTF_8));
            urlBuilder.append(EQUALS);
            urlBuilder.append(URLEncoder.encode(param.getValue(), StandardCharsets.UTF_8));
        }

        return urlBuilder.toString();
    }


    /**
     * 发送POST请求
     *
     * @param url         请求的URL
     * @param requestBody 请求体内容
     * @return 响应字符串
     * @throws Exception 如果发生任何错误
     */
    public static String doPost(String url, String requestBody) throws IOException, InterruptedException {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(requestBody, StandardCharsets.UTF_8))
                .build();

        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
        return response.body();
    }

    /**
     * 发送POST请求
     *
     * @param url         请求的URL
     * @param requestBody 请求体内容
     * @return 响应字符串
     * @throws Exception 如果发生任何错误
     */
    public static String doPostWithHeaders(String url, Map<String, String> headers, String requestBody) throws IOException, InterruptedException {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .headers(headers.entrySet().stream()
                        .flatMap(e -> Stream.of(e.getKey(), e.getValue()))
                        .toArray(String[]::new))
                .header("Content-Type", "application/json") // 确保设置Content-Type
                .POST(HttpRequest.BodyPublishers.ofString(requestBody, StandardCharsets.UTF_8))
                .build();

        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

        return response.body();
    }


    private static ThreadPoolTaskExecutor createExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 设置核心线程数
        executor.setCorePoolSize(10);
        // 设置最大线程数
        executor.setMaxPoolSize(50);
        // 设置队列容量
        executor.setQueueCapacity(100);
        // 设置线程活跃时间（秒）
        executor.setKeepAliveSeconds(60);
        // 设置默认线程名称
        executor.setThreadNamePrefix("HttpClientExecutor-");
        // 当设置为 true 时，shutdown() 会阻塞，直到线程池中的所有任务（包括正在执行的任务）完成后才会返回
        executor.setWaitForTasksToCompleteOnShutdown(true);
        // 设置线程池关闭前等待所有任务完成的时间
        executor.setAwaitTerminationSeconds(60);
        // 初始化线程池
        executor.initialize();
        return executor;
    }
}
